#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>

long *src;
long result;

void recordTime(struct timeval* current)
{
  gettimeofday(current, NULL);

  return;
}

float diffTime(struct timeval before, struct timeval after)
{
  float time_sec = ((after.tv_sec - before.tv_sec) + ((after.tv_usec - before.tv_usec) / 1000000.0));

  return time_sec;
}

void pranith_start() {}
void pranith_stop() {}

int main()
{
  unsigned long size = 256 * 1024 * 1024 / sizeof(long); // 256 MB
  src = (long *)malloc(sizeof(long) * size);
  unsigned long i = 0, j, k = 0, l;
  volatile long dest;
  int num_mem_ops = 400;

  unsigned long num_iter = 4000;// / num_mem_ops;
  struct timeval before, after;

  //initialize array
  for (j = 0; j < size; j++)
    src[j] = 8;

  int inc = 1;
  int max = inc * 400;
  int num_req = 0;
  int final = 0;
  /*
   * to generate 'n' requests we use the formula src[i + (8 * num_req * iteration)/400]
   *
   * this will generate 'n' requests over the entire iteration
   */
  for (num_req = 1; num_req < 2; num_req+=1)
  {
    fprintf(stderr, "trying for num_req %d\n", num_req);
    pranith_start();
    recordTime(&before);
    for(j = 0; j < num_iter; j++)
    {
      dest = src[i + ((num_req * 0) / 50)];
      dest = src[i + ((num_req * 1) / 50)];
      dest = src[i + ((num_req * 2) / 50)];
      dest = src[i + ((num_req * 3) / 50)];
      dest = src[i + ((num_req * 4) / 50)];
      dest = src[i + ((num_req * 5) / 50)];
      dest = src[i + ((num_req * 6) / 50)];
      dest = src[i + ((num_req * 7) / 50)];
      dest = src[i + ((num_req * 8) / 50)];
      dest = src[i + ((num_req * 9) / 50)];
      dest = src[i + ((num_req * 10) / 50)];
      dest = src[i + ((num_req * 11) / 50)];
      dest = src[i + ((num_req * 12) / 50)];
      dest = src[i + ((num_req * 13) / 50)];
      dest = src[i + ((num_req * 14) / 50)];
      dest = src[i + ((num_req * 15) / 50)];
      dest = src[i + ((num_req * 16) / 50)];
      dest = src[i + ((num_req * 17) / 50)];
      dest = src[i + ((num_req * 18) / 50)];
      dest = src[i + ((num_req * 19) / 50)];
      dest = src[i + ((num_req * 20) / 50)];
      dest = src[i + ((num_req * 21) / 50)];
      dest = src[i + ((num_req * 22) / 50)];
      dest = src[i + ((num_req * 23) / 50)];
      dest = src[i + ((num_req * 24) / 50)];
      dest = src[i + ((num_req * 25) / 50)];
      dest = src[i + ((num_req * 26) / 50)];
      dest = src[i + ((num_req * 27) / 50)];
      dest = src[i + ((num_req * 28) / 50)];
      dest = src[i + ((num_req * 29) / 50)];
      dest = src[i + ((num_req * 30) / 50)];
      dest = src[i + ((num_req * 31) / 50)];
      dest = src[i + ((num_req * 32) / 50)];
      dest = src[i + ((num_req * 33) / 50)];
      dest = src[i + ((num_req * 34) / 50)];
      dest = src[i + ((num_req * 35) / 50)];
      dest = src[i + ((num_req * 36) / 50)];
      dest = src[i + ((num_req * 37) / 50)];
      dest = src[i + ((num_req * 38) / 50)];
      dest = src[i + ((num_req * 39) / 50)];
      dest = src[i + ((num_req * 40) / 50)];
      dest = src[i + ((num_req * 41) / 50)];
      dest = src[i + ((num_req * 42) / 50)];
      dest = src[i + ((num_req * 43) / 50)];
      dest = src[i + ((num_req * 44) / 50)];
      dest = src[i + ((num_req * 45) / 50)];
      dest = src[i + ((num_req * 46) / 50)];
      dest = src[i + ((num_req * 47) / 50)];
      dest = src[i + ((num_req * 48) / 50)];
      dest = src[i + ((num_req * 49) / 50)];
      dest = src[i + ((num_req * 50) / 50)];
      dest = src[i + ((num_req * 51) / 50)];
      dest = src[i + ((num_req * 52) / 50)];
      dest = src[i + ((num_req * 53) / 50)];
      dest = src[i + ((num_req * 54) / 50)];
      dest = src[i + ((num_req * 55) / 50)];
      dest = src[i + ((num_req * 56) / 50)];
      dest = src[i + ((num_req * 57) / 50)];
      dest = src[i + ((num_req * 58) / 50)];
      dest = src[i + ((num_req * 59) / 50)];
      dest = src[i + ((num_req * 60) / 50)];
      dest = src[i + ((num_req * 61) / 50)];
      dest = src[i + ((num_req * 62) / 50)];
      dest = src[i + ((num_req * 63) / 50)];
      dest = src[i + ((num_req * 64) / 50)];
      dest = src[i + ((num_req * 65) / 50)];
      dest = src[i + ((num_req * 66) / 50)];
      dest = src[i + ((num_req * 67) / 50)];
      dest = src[i + ((num_req * 68) / 50)];
      dest = src[i + ((num_req * 69) / 50)];
      dest = src[i + ((num_req * 70) / 50)];
      dest = src[i + ((num_req * 71) / 50)];
      dest = src[i + ((num_req * 72) / 50)];
      dest = src[i + ((num_req * 73) / 50)];
      dest = src[i + ((num_req * 74) / 50)];
      dest = src[i + ((num_req * 75) / 50)];
      dest = src[i + ((num_req * 76) / 50)];
      dest = src[i + ((num_req * 77) / 50)];
      dest = src[i + ((num_req * 78) / 50)];
      dest = src[i + ((num_req * 79) / 50)];
      dest = src[i + ((num_req * 80) / 50)];
      dest = src[i + ((num_req * 81) / 50)];
      dest = src[i + ((num_req * 82) / 50)];
      dest = src[i + ((num_req * 83) / 50)];
      dest = src[i + ((num_req * 84) / 50)];
      dest = src[i + ((num_req * 85) / 50)];
      dest = src[i + ((num_req * 86) / 50)];
      dest = src[i + ((num_req * 87) / 50)];
      dest = src[i + ((num_req * 88) / 50)];
      dest = src[i + ((num_req * 89) / 50)];
      dest = src[i + ((num_req * 90) / 50)];
      dest = src[i + ((num_req * 91) / 50)];
      dest = src[i + ((num_req * 92) / 50)];
      dest = src[i + ((num_req * 93) / 50)];
      dest = src[i + ((num_req * 94) / 50)];
      dest = src[i + ((num_req * 95) / 50)];
      dest = src[i + ((num_req * 96) / 50)];
      dest = src[i + ((num_req * 97) / 50)];
      dest = src[i + ((num_req * 98) / 50)];
      dest = src[i + ((num_req * 99) / 50)];
      dest = src[i + ((num_req * 100) / 50)];
      dest = src[i + ((num_req * 101) / 50)];
      dest = src[i + ((num_req * 102) / 50)];
      dest = src[i + ((num_req * 103) / 50)];
      dest = src[i + ((num_req * 104) / 50)];
      dest = src[i + ((num_req * 105) / 50)];
      dest = src[i + ((num_req * 106) / 50)];
      dest = src[i + ((num_req * 107) / 50)];
      dest = src[i + ((num_req * 108) / 50)];
      dest = src[i + ((num_req * 109) / 50)];
      dest = src[i + ((num_req * 110) / 50)];
      dest = src[i + ((num_req * 111) / 50)];
      dest = src[i + ((num_req * 112) / 50)];
      dest = src[i + ((num_req * 113) / 50)];
      dest = src[i + ((num_req * 114) / 50)];
      dest = src[i + ((num_req * 115) / 50)];
      dest = src[i + ((num_req * 116) / 50)];
      dest = src[i + ((num_req * 117) / 50)];
      dest = src[i + ((num_req * 118) / 50)];
      dest = src[i + ((num_req * 119) / 50)];
      dest = src[i + ((num_req * 120) / 50)];
      dest = src[i + ((num_req * 121) / 50)];
      dest = src[i + ((num_req * 122) / 50)];
      dest = src[i + ((num_req * 123) / 50)];
      dest = src[i + ((num_req * 124) / 50)];
      dest = src[i + ((num_req * 125) / 50)];
      dest = src[i + ((num_req * 126) / 50)];
      dest = src[i + ((num_req * 127) / 50)];
      dest = src[i + ((num_req * 128) / 50)];
      dest = src[i + ((num_req * 129) / 50)];
      dest = src[i + ((num_req * 130) / 50)];
      dest = src[i + ((num_req * 131) / 50)];
      dest = src[i + ((num_req * 132) / 50)];
      dest = src[i + ((num_req * 133) / 50)];
      dest = src[i + ((num_req * 134) / 50)];
      dest = src[i + ((num_req * 135) / 50)];
      dest = src[i + ((num_req * 136) / 50)];
      dest = src[i + ((num_req * 137) / 50)];
      dest = src[i + ((num_req * 138) / 50)];
      dest = src[i + ((num_req * 139) / 50)];
      dest = src[i + ((num_req * 140) / 50)];
      dest = src[i + ((num_req * 141) / 50)];
      dest = src[i + ((num_req * 142) / 50)];
      dest = src[i + ((num_req * 143) / 50)];
      dest = src[i + ((num_req * 144) / 50)];
      dest = src[i + ((num_req * 145) / 50)];
      dest = src[i + ((num_req * 146) / 50)];
      dest = src[i + ((num_req * 147) / 50)];
      dest = src[i + ((num_req * 148) / 50)];
      dest = src[i + ((num_req * 149) / 50)];
      dest = src[i + ((num_req * 150) / 50)];
      dest = src[i + ((num_req * 151) / 50)];
      dest = src[i + ((num_req * 152) / 50)];
      dest = src[i + ((num_req * 153) / 50)];
      dest = src[i + ((num_req * 154) / 50)];
      dest = src[i + ((num_req * 155) / 50)];
      dest = src[i + ((num_req * 156) / 50)];
      dest = src[i + ((num_req * 157) / 50)];
      dest = src[i + ((num_req * 158) / 50)];
      dest = src[i + ((num_req * 159) / 50)];
      dest = src[i + ((num_req * 160) / 50)];
      dest = src[i + ((num_req * 161) / 50)];
      dest = src[i + ((num_req * 162) / 50)];
      dest = src[i + ((num_req * 163) / 50)];
      dest = src[i + ((num_req * 164) / 50)];
      dest = src[i + ((num_req * 165) / 50)];
      dest = src[i + ((num_req * 166) / 50)];
      dest = src[i + ((num_req * 167) / 50)];
      dest = src[i + ((num_req * 168) / 50)];
      dest = src[i + ((num_req * 169) / 50)];
      dest = src[i + ((num_req * 170) / 50)];
      dest = src[i + ((num_req * 171) / 50)];
      dest = src[i + ((num_req * 172) / 50)];
      dest = src[i + ((num_req * 173) / 50)];
      dest = src[i + ((num_req * 174) / 50)];
      dest = src[i + ((num_req * 175) / 50)];
      dest = src[i + ((num_req * 176) / 50)];
      dest = src[i + ((num_req * 177) / 50)];
      dest = src[i + ((num_req * 178) / 50)];
      dest = src[i + ((num_req * 179) / 50)];
      dest = src[i + ((num_req * 180) / 50)];
      dest = src[i + ((num_req * 181) / 50)];
      dest = src[i + ((num_req * 182) / 50)];
      dest = src[i + ((num_req * 183) / 50)];
      dest = src[i + ((num_req * 184) / 50)];
      dest = src[i + ((num_req * 185) / 50)];
      dest = src[i + ((num_req * 186) / 50)];
      dest = src[i + ((num_req * 187) / 50)];
      dest = src[i + ((num_req * 188) / 50)];
      dest = src[i + ((num_req * 189) / 50)];
      dest = src[i + ((num_req * 190) / 50)];
      dest = src[i + ((num_req * 191) / 50)];
      dest = src[i + ((num_req * 192) / 50)];
      dest = src[i + ((num_req * 193) / 50)];
      dest = src[i + ((num_req * 194) / 50)];
      dest = src[i + ((num_req * 195) / 50)];
      dest = src[i + ((num_req * 196) / 50)];
      dest = src[i + ((num_req * 197) / 50)];
      dest = src[i + ((num_req * 198) / 50)];
      dest = src[i + ((num_req * 199) / 50)];
      dest = src[i + ((num_req * 200) / 50)];
      dest = src[i + ((num_req * 201) / 50)];
      dest = src[i + ((num_req * 202) / 50)];
      dest = src[i + ((num_req * 203) / 50)];
      dest = src[i + ((num_req * 204) / 50)];
      dest = src[i + ((num_req * 205) / 50)];
      dest = src[i + ((num_req * 206) / 50)];
      dest = src[i + ((num_req * 207) / 50)];
      dest = src[i + ((num_req * 208) / 50)];
      dest = src[i + ((num_req * 209) / 50)];
      dest = src[i + ((num_req * 210) / 50)];
      dest = src[i + ((num_req * 211) / 50)];
      dest = src[i + ((num_req * 212) / 50)];
      dest = src[i + ((num_req * 213) / 50)];
      dest = src[i + ((num_req * 214) / 50)];
      dest = src[i + ((num_req * 215) / 50)];
      dest = src[i + ((num_req * 216) / 50)];
      dest = src[i + ((num_req * 217) / 50)];
      dest = src[i + ((num_req * 218) / 50)];
      dest = src[i + ((num_req * 219) / 50)];
      dest = src[i + ((num_req * 220) / 50)];
      dest = src[i + ((num_req * 221) / 50)];
      dest = src[i + ((num_req * 222) / 50)];
      dest = src[i + ((num_req * 223) / 50)];
      dest = src[i + ((num_req * 224) / 50)];
      dest = src[i + ((num_req * 225) / 50)];
      dest = src[i + ((num_req * 226) / 50)];
      dest = src[i + ((num_req * 227) / 50)];
      dest = src[i + ((num_req * 228) / 50)];
      dest = src[i + ((num_req * 229) / 50)];
      dest = src[i + ((num_req * 230) / 50)];
      dest = src[i + ((num_req * 231) / 50)];
      dest = src[i + ((num_req * 232) / 50)];
      dest = src[i + ((num_req * 233) / 50)];
      dest = src[i + ((num_req * 234) / 50)];
      dest = src[i + ((num_req * 235) / 50)];
      dest = src[i + ((num_req * 236) / 50)];
      dest = src[i + ((num_req * 237) / 50)];
      dest = src[i + ((num_req * 238) / 50)];
      dest = src[i + ((num_req * 239) / 50)];
      dest = src[i + ((num_req * 240) / 50)];
      dest = src[i + ((num_req * 241) / 50)];
      dest = src[i + ((num_req * 242) / 50)];
      dest = src[i + ((num_req * 243) / 50)];
      dest = src[i + ((num_req * 244) / 50)];
      dest = src[i + ((num_req * 245) / 50)];
      dest = src[i + ((num_req * 246) / 50)];
      dest = src[i + ((num_req * 247) / 50)];
      dest = src[i + ((num_req * 248) / 50)];
      dest = src[i + ((num_req * 249) / 50)];
      dest = src[i + ((num_req * 250) / 50)];
      dest = src[i + ((num_req * 251) / 50)];
      dest = src[i + ((num_req * 252) / 50)];
      dest = src[i + ((num_req * 253) / 50)];
      dest = src[i + ((num_req * 254) / 50)];
      dest = src[i + ((num_req * 255) / 50)];
      dest = src[i + ((num_req * 256) / 50)];
      dest = src[i + ((num_req * 257) / 50)];
      dest = src[i + ((num_req * 258) / 50)];
      dest = src[i + ((num_req * 259) / 50)];
      dest = src[i + ((num_req * 260) / 50)];
      dest = src[i + ((num_req * 261) / 50)];
      dest = src[i + ((num_req * 262) / 50)];
      dest = src[i + ((num_req * 263) / 50)];
      dest = src[i + ((num_req * 264) / 50)];
      dest = src[i + ((num_req * 265) / 50)];
      dest = src[i + ((num_req * 266) / 50)];
      dest = src[i + ((num_req * 267) / 50)];
      dest = src[i + ((num_req * 268) / 50)];
      dest = src[i + ((num_req * 269) / 50)];
      dest = src[i + ((num_req * 270) / 50)];
      dest = src[i + ((num_req * 271) / 50)];
      dest = src[i + ((num_req * 272) / 50)];
      dest = src[i + ((num_req * 273) / 50)];
      dest = src[i + ((num_req * 274) / 50)];
      dest = src[i + ((num_req * 275) / 50)];
      dest = src[i + ((num_req * 276) / 50)];
      dest = src[i + ((num_req * 277) / 50)];
      dest = src[i + ((num_req * 278) / 50)];
      dest = src[i + ((num_req * 279) / 50)];
      dest = src[i + ((num_req * 280) / 50)];
      dest = src[i + ((num_req * 281) / 50)];
      dest = src[i + ((num_req * 282) / 50)];
      dest = src[i + ((num_req * 283) / 50)];
      dest = src[i + ((num_req * 284) / 50)];
      dest = src[i + ((num_req * 285) / 50)];
      dest = src[i + ((num_req * 286) / 50)];
      dest = src[i + ((num_req * 287) / 50)];
      dest = src[i + ((num_req * 288) / 50)];
      dest = src[i + ((num_req * 289) / 50)];
      dest = src[i + ((num_req * 290) / 50)];
      dest = src[i + ((num_req * 291) / 50)];
      dest = src[i + ((num_req * 292) / 50)];
      dest = src[i + ((num_req * 293) / 50)];
      dest = src[i + ((num_req * 294) / 50)];
      dest = src[i + ((num_req * 295) / 50)];
      dest = src[i + ((num_req * 296) / 50)];
      dest = src[i + ((num_req * 297) / 50)];
      dest = src[i + ((num_req * 298) / 50)];
      dest = src[i + ((num_req * 299) / 50)];
      dest = src[i + ((num_req * 300) / 50)];
      dest = src[i + ((num_req * 301) / 50)];
      dest = src[i + ((num_req * 302) / 50)];
      dest = src[i + ((num_req * 303) / 50)];
      dest = src[i + ((num_req * 304) / 50)];
      dest = src[i + ((num_req * 305) / 50)];
      dest = src[i + ((num_req * 306) / 50)];
      dest = src[i + ((num_req * 307) / 50)];
      dest = src[i + ((num_req * 308) / 50)];
      dest = src[i + ((num_req * 309) / 50)];
      dest = src[i + ((num_req * 310) / 50)];
      dest = src[i + ((num_req * 311) / 50)];
      dest = src[i + ((num_req * 312) / 50)];
      dest = src[i + ((num_req * 313) / 50)];
      dest = src[i + ((num_req * 314) / 50)];
      dest = src[i + ((num_req * 315) / 50)];
      dest = src[i + ((num_req * 316) / 50)];
      dest = src[i + ((num_req * 317) / 50)];
      dest = src[i + ((num_req * 318) / 50)];
      dest = src[i + ((num_req * 319) / 50)];
      dest = src[i + ((num_req * 320) / 50)];
      dest = src[i + ((num_req * 321) / 50)];
      dest = src[i + ((num_req * 322) / 50)];
      dest = src[i + ((num_req * 323) / 50)];
      dest = src[i + ((num_req * 324) / 50)];
      dest = src[i + ((num_req * 325) / 50)];
      dest = src[i + ((num_req * 326) / 50)];
      dest = src[i + ((num_req * 327) / 50)];
      dest = src[i + ((num_req * 328) / 50)];
      dest = src[i + ((num_req * 329) / 50)];
      dest = src[i + ((num_req * 330) / 50)];
      dest = src[i + ((num_req * 331) / 50)];
      dest = src[i + ((num_req * 332) / 50)];
      dest = src[i + ((num_req * 333) / 50)];
      dest = src[i + ((num_req * 334) / 50)];
      dest = src[i + ((num_req * 335) / 50)];
      dest = src[i + ((num_req * 336) / 50)];
      dest = src[i + ((num_req * 337) / 50)];
      dest = src[i + ((num_req * 338) / 50)];
      dest = src[i + ((num_req * 339) / 50)];
      dest = src[i + ((num_req * 340) / 50)];
      dest = src[i + ((num_req * 341) / 50)];
      dest = src[i + ((num_req * 342) / 50)];
      dest = src[i + ((num_req * 343) / 50)];
      dest = src[i + ((num_req * 344) / 50)];
      dest = src[i + ((num_req * 345) / 50)];
      dest = src[i + ((num_req * 346) / 50)];
      dest = src[i + ((num_req * 347) / 50)];
      dest = src[i + ((num_req * 348) / 50)];
      dest = src[i + ((num_req * 349) / 50)];
      dest = src[i + ((num_req * 350) / 50)];
      dest = src[i + ((num_req * 351) / 50)];
      dest = src[i + ((num_req * 352) / 50)];
      dest = src[i + ((num_req * 353) / 50)];
      dest = src[i + ((num_req * 354) / 50)];
      dest = src[i + ((num_req * 355) / 50)];
      dest = src[i + ((num_req * 356) / 50)];
      dest = src[i + ((num_req * 357) / 50)];
      dest = src[i + ((num_req * 358) / 50)];
      dest = src[i + ((num_req * 359) / 50)];
      dest = src[i + ((num_req * 360) / 50)];
      dest = src[i + ((num_req * 361) / 50)];
      dest = src[i + ((num_req * 362) / 50)];
      dest = src[i + ((num_req * 363) / 50)];
      dest = src[i + ((num_req * 364) / 50)];
      dest = src[i + ((num_req * 365) / 50)];
      dest = src[i + ((num_req * 366) / 50)];
      dest = src[i + ((num_req * 367) / 50)];
      dest = src[i + ((num_req * 368) / 50)];
      dest = src[i + ((num_req * 369) / 50)];
      dest = src[i + ((num_req * 370) / 50)];
      dest = src[i + ((num_req * 371) / 50)];
      dest = src[i + ((num_req * 372) / 50)];
      dest = src[i + ((num_req * 373) / 50)];
      dest = src[i + ((num_req * 374) / 50)];
      dest = src[i + ((num_req * 375) / 50)];
      dest = src[i + ((num_req * 376) / 50)];
      dest = src[i + ((num_req * 377) / 50)];
      dest = src[i + ((num_req * 378) / 50)];
      dest = src[i + ((num_req * 379) / 50)];
      dest = src[i + ((num_req * 380) / 50)];
      dest = src[i + ((num_req * 381) / 50)];
      dest = src[i + ((num_req * 382) / 50)];
      dest = src[i + ((num_req * 383) / 50)];
      dest = src[i + ((num_req * 384) / 50)];
      dest = src[i + ((num_req * 385) / 50)];
      dest = src[i + ((num_req * 386) / 50)];
      dest = src[i + ((num_req * 387) / 50)];
      dest = src[i + ((num_req * 388) / 50)];
      dest = src[i + ((num_req * 389) / 50)];
      dest = src[i + ((num_req * 390) / 50)];
      dest = src[i + ((num_req * 391) / 50)];
      dest = src[i + ((num_req * 392) / 50)];
      dest = src[i + ((num_req * 393) / 50)];
      dest = src[i + ((num_req * 394) / 50)];
      dest = src[i + ((num_req * 395) / 50)];
      dest = src[i + ((num_req * 396) / 50)];
      dest = src[i + ((num_req * 397) / 50)];
      dest = src[i + ((num_req * 398) / 50)];
      dest = src[i + ((num_req * 399) / 50)];
      i += (dest * num_req);

      if (i + (num_req * 399)/50 >= size)
        i = 0;

      final += dest;
    }
    recordTime(&after);
    pranith_stop();
    printf("%d %f\n", num_req, diffTime(before, after));
    fprintf(stderr, "%d %f\n", num_req, diffTime(before, after));
    fflush(NULL);
  }

  result = final;

  return 0;
}
